<?php


namespace app\api\service;


use app\api\model\UserFalse;
use app\api\model\UserRecord;
use app\api\model\UserRegistered;
use app\api\model\UserTrue;
use app\api\model\XinyongRecord;
use app\common\controller\UserPhone;
use app\lib\exception\ParameterException;
use Driver\Cache\Redis;
use think\facade\Request;

class UserPhoneService
{
    /**
     * @param $phone_md5 手机号码
     * @param $registerFrom 标识码
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function user_check($phone_md5, $registerFrom, $check = true)
    {
        if($check){
            $this->check_register_from($registerFrom);
        }
        $in_true_mysql = $this->find_in_true_sql($phone_md5);
        if($in_true_mysql == false){
            $re = $this->find_in_false_sql($phone_md5, $registerFrom);
            return $re;
        }
        return $this->has_phone();
    }

    /**
     * 注册撞库成功的手机号码
     * @param $phone 手机号码
     * @param $registerFrom 推广标识
     * @return array
     * @throws ParameterException
     */
    public function user_register($phone, $registerFrom)
    {
        $re = $this->user_check(md5($phone), $registerFrom, false);
        $arr = $this->check_register_from($registerFrom);
        if($re['code'] == '0001'){
            return $re;
        }
        $data = $this->add_register_list($arr['from'], $arr['sign'], $phone);
        return $data;
    }

    public function xinyong_third_login($post)
    {
        # 校验参数是否合法
        $arr = $this->check_register_from($post['channel'], 'channel');
        $re = $this->xinyong_find_md5_phone($post, $arr);
        $logo = $this->get_logo($arr['from']);
        $re['url'] = config('redis.zk_download').$logo;
        return $re;
    }

    /**
     * 查找撞库true数据库是否存在改md5手机号码
     * @param $phone_md5
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function find_in_true_sql($phone_md5)
    {
        $model = new UserTrue();
        $list = $model->where('phone_md5', '=', $phone_md5)
            ->find();
        if($list){
            return true;
        }
        return false;
    }

    /**
     * 查找flase撞库数据库
     * @param $phone_md5 手机号码对应的md5
     * @param $sign 标识
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function find_in_false_sql($phone_md5, $sign)
    {
        $model = new UserFalse();
        $re = $model->where('phone_md5', '=', $phone_md5)
            ->find();
        if(!$re){
            $this->add_user_record_list(2, $phone_md5, $sign);
            return ['code' => '0000', 'msg' => 'success', 'businessCode' => '0000'];
        }
        $this->add_user_record_list(-1, $phone_md5, $sign, $re['phone']);
        return $this->has_phone();
    }

    # 放回已经撞库的信息
    private function has_phone()
    {
        return ['code' => '0001', 'msg' => '该用户已撞库', 'businessCode' => '0001'];
    }

    # 添加调用记录
    private function add_user_record_list($type, $phone_md5, $register_from=null, $phone=null)
    {
        $model = new UserRecord();
        $data = [
            'type' => $type,
            'phone_md5' => $phone_md5,
            'phone' => $phone,
            'register_from' => $register_from,
            'ip' => Request::ip(),
            'add_time' => now_time(),
            'ip' => Request::ip()
        ];
        $model->create($data);
    }

    /**
     * 校验渠道参数
     * @param $registerFrom 请求渠道来源
     * @return array
     * @throws ParameterException
     */
    private function check_register_from($registerFrom, $msg='registerFrom')
    {
        $arr = explode('_', $registerFrom);
        if(count($arr) !== 2){
            throw new ParameterException([
                'msg' => $msg.'格式不对',
            ]);
        }
        $redis_key = config('redis.all_sign').$arr[0];
        if(Redis::sismember($redis_key, $arr[1]) == false){
            throw new ParameterException([
                'msg' => '不合法'.$msg,
            ]);
        }
        return [
            'from' => $arr[0],
            'sign' => $arr[1],
        ];
    }

    /**
     * 成功转库把手机号码添加到true数据库
     * @param $from
     * @param $sign
     * @param $phone
     */
    private function add_register_list($from, $sign, $phone)
    {
        $data = [
            'from' => $from,
            'sign' => $sign,
            'phone' => $phone,
            'ip' => Request::ip(),
            'add_time' => now_time()
        ];
        $model = new UserRegistered();
        $model->create($data);
        $logo = $this->get_logo($from);
        $service = new UserPhone();
        $service->add_user_true($phone, $logo, 4);
        return [
            'code' => '0000',
            'msg' => 'success',
            "businessCode" => "0000",
            'url' => config('redis.zk_download').$logo
        ];
    }

    /**
     * 判断手机号码是否在true和false库中出现过
     * @param $phone_md5
     * @param $arr
     * @return array|bool {"false":"没有出现"}
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function xinyong_find_md5_phone($post, $arr)
    {
        $post = $this->return_new_xinyong_post_data($post, $arr);
        $true_model = new UserTrue();
        $true_has_phone = $true_model->where('phone_md5', '=', $post['phone_md5'])
            ->find();
        if(!$true_has_phone){
            $false_model = new UserFalse();
            $false_has_phone = $false_model->where('phone_md5', '=', $post['phone_md5'])
                ->find();
            if(!$false_has_phone){
                $this->add_list_to_xingyong_record($post, -1);
                return ['code' => 200, 'msg' => '新用户', 'userType' => 0];
            }
            $post['phone'] = $false_has_phone['phone'];
            $this->add_list_to_xingyong_record($post, 2);
            return $this->xinyong_return_true();
        }
        $post['phone'] = $true_has_phone['phone'];
        $this->add_list_to_xingyong_record($post, 1);
        return $this->xinyong_return_true();
    }

    # 在数据库中能找到的要放回的详情（信用管家）
    private function xinyong_return_true()
    {
        return [
            'code' => 200,
            'msg' => '老用户',
            'userType' => 1
        ];
    }

    # （信用管家）组装一个新的post数组
    private function return_new_xinyong_post_data($post, $arr)
    {
        unset($post['channel']);
        $phone_md5 = $post['phone'];
        unset($post['phone']);
        $post['phone_md5'] = $phone_md5;
        $post['from'] = $arr['from'];
        $post['sign'] = $arr['sign'];
        if(array_key_exists('deviceType', $post)){
            $post['deviceType'] = $post['deviceType'] == 'IOS' ? '1' : 2;
        }
        $post['add_time'] = now_time();
        return $post;
    }

    /**
     * 往数据库中添加调用接口的记录
     * @param $post
     * @param $type
     */
    private function add_list_to_xingyong_record($post, $type)
    {
        $model = new XinyongRecord();
        $post['sql_type'] = $type;
        $model->create($post);
    }

    /**
     * 根据标识获取对应商户的logo
     * @param $from 商户标识
     * @return array|string
     */
    private function get_logo($from)
    {
        $redis_hash_key = config('redis.account').$from;
        $logo = Redis::hget($redis_hash_key, 'logo');
        return $logo;
    }
}